package com.abetsy.vben.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.abetsy.vben.dao.GlobalConfigMapper;
import com.abetsy.vben.entity.GlobalConfig;
import com.abetsy.vben.entity.constant.TMDBConstant;
import com.abetsy.vben.service.GlobalConfigService;
import com.abetsy.vben.utils.FnosUtil;
import com.abetsy.vben.utils.i18n.VbenException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

@Service
public class GlobalConfigServiceImpl implements GlobalConfigService {

    @Resource
    private GlobalConfigMapper globalConfigMapper;

    @Override
    public GlobalConfig getConfig() {
        int userId = Integer.parseInt(StpUtil.getLoginId().toString());
        QueryWrapper<GlobalConfig> configQueryWrapper = new QueryWrapper<>();
        configQueryWrapper.eq("user_id", userId);
        GlobalConfig globalConfig = globalConfigMapper.selectOne(configQueryWrapper);
        if (globalConfig == null) {
            globalConfig = new GlobalConfig();
            globalConfig.setUserId(userId);
            globalConfig.setProxyActivate(false);
            globalConfigMapper.insert(globalConfig);
        }
        return globalConfig;
    }

    @Override
    public GlobalConfig setConfig(GlobalConfig globalConfig) {
        if (globalConfig == null ) {
            VbenException.locale("globalconfig.param.error");
        }
        checkFnosSetting(globalConfig);
        checkProxySetting(globalConfig);
        int userId = Integer.parseInt(StpUtil.getLoginId().toString());
        globalConfig.setUserId(userId);
        globalConfigMapper.insertOrUpdate(globalConfig);
        return globalConfig;
    }

    private void checkFnosSetting(GlobalConfig globalConfig) {
        if (StrUtil.isEmpty(globalConfig.getFnosIp())){
            VbenException.locale("fnos.ip.empty");
        }else {
            Map<String, String> hostEnv = new HashMap<>();
            try {
                String protocol = globalConfig.isFnosSsl() ? "https" : "http";
                InetAddress[] addresses = InetAddress.getAllByName(globalConfig.getFnosIp());
                for (InetAddress address : addresses) {
                    if (address.isReachable(2000)) {
                        String hostAddress = address.getHostAddress();
                        int port = globalConfig.getFnosPort();
                        if (address.getAddress().length == 4) {
                            hostEnv.put("IPV4", String.format("%s://%s:%d", protocol, hostAddress, port));
                        } else if (address.getAddress().length == 16) {
                            hostEnv.put("IPV6", String.format("%s://[%s]:%d", protocol, hostAddress, port));
                        }
                    }
                }
            } catch (Exception ignored) {}
            String hostUrl = hostEnv.getOrDefault(globalConfig.isFnosIpType() ? "IPV6" : "IPV4", "");
            if (StrUtil.isEmpty(hostUrl)) {
                VbenException.locale("fnos.ip.unreachable");
            }
            boolean flag = FnosUtil.getInstance().loginCheck(hostUrl, globalConfig.getFnosUser(), globalConfig.getFnosPassWd());
            if (!flag) {
                VbenException.locale("fnos.unreachable");
            }
        }
    }

    private void checkProxySetting(GlobalConfig globalConfig) {
        if (globalConfig.isProxyActivate()){
            if (StrUtil.isEmpty(globalConfig.getProxyIp())){
                VbenException.locale("proxyip.empty");
            }else {
                if (NetUtil.ping(globalConfig.getProxyIp())){
                    try {
                        HttpRequest.get(TMDBConstant.BASE_URL).setHttpProxy(globalConfig.getProxyIp(), globalConfig.getProxyPort()).execute();
                    }catch (Exception e){
                        VbenException.locale("proxyip.Invalid");
                    }
                }else {
                    VbenException.locale("proxyip.ping.error");
                }
            }
        }
    }

}
